package com.android.xk.mask.client

import com.android.xk.mask.BuildConfig
import com.apkfuns.logutils.LogUtils
import io.netty.bootstrap.Bootstrap
import io.netty.channel.ChannelFuture
import io.netty.channel.ChannelFutureListener
import io.netty.channel.ChannelOption
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioSocketChannel
import io.netty.handler.logging.LogLevel
import io.netty.handler.logging.LoggingHandler
import io.reactivex.Observable
import java.util.concurrent.TimeUnit


object SocketClient
{


    private var mHost = ""

    private var mPort = 8000

    private var mChannelFuture: ChannelFuture? = null

    private val mBootstrap by lazy {
        Bootstrap().channel(NioSocketChannel::class.java)
                .group(NioEventLoopGroup())
                .option(ChannelOption.TCP_NODELAY, true)
                .option(ChannelOption.SO_REUSEADDR, true)
                .handler(LoggingHandler(if (BuildConfig.DEBUG) LogLevel.DEBUG else LogLevel.INFO))
                .handler(ClientChannelInitializer())
    }

    fun connect(host: String, port: Int)
    {
        mHost = host
        mPort = port
        mChannelFuture = mBootstrap.connect(host, port)
        mChannelFuture?.addListener(object : ChannelFutureListener
        {
            override fun operationComplete(future: ChannelFuture)
            {
                if (future.isSuccess)
                {
                    LogUtils.i("连接服务器成功")
                }
                else
                {
                    LogUtils.e("连接服务器失败,重新连接服务器")
                    Observable.timer(2,TimeUnit.SECONDS).subscribe { reconnect() }
                }
            }

        })
    }

    fun disconnect()
    {
        mChannelFuture?.channel()?.disconnect()
        LogUtils.e("断开服务器连接")
    }

    fun close() = mChannelFuture?.channel()?.close()

    fun reconnect()
    {
        if (!isConnected())
        {
            LogUtils.e("重连服务器")
            connect(mHost, mPort)
        }

    }

    fun isConnected() = mChannelFuture?.channel()?.isActive ?: false

    fun isOpen() = mChannelFuture?.channel()?.isOpen ?: false


    fun send(msg: Any?)
    {
        msg?.let {
            if (isConnected())
                mChannelFuture?.channel()?.writeAndFlush(it)
        }
    }
}